<template>
  <page-meta :root-font-size="rootFontSize() + 'px'"></page-meta>

  <view class="page-container" v-show="delayShow">
    <customHeader isShowProcess :progress="progress" title="情景对话" :border-line="false" />

    <view class="scene-container" :style="{ top: height }">
      <view class="scene-wrapper">
        <view class="scene-label">根据听到问题，口语输出选择</view>
        <view class="scene-doubt">
          <loudspeaker class="horn" :voice="curSceneSpeak.us_voice" isAutoPlay />
          <image class="person" :src="`${env.prefixUrl}${curSceneSpeak?.img}`" />
        </view>
        <template v-if="Array.isArray(curSceneSpeak.option)">
          <view class="scene-answer">You say：</view>
          <view
            :class="['scene-option', typeof currentIndex === 'number' ? (currentIndex === index ? 'active' : 'un-active') : 'active']"
            v-for="(item, index) in curSceneSpeak.option" :key="item.scene_speak_id">
            <view class="option-tag">{{ optionTags[index] }}.</view>
            <sentence class="option-label"
              :markedColor="typeof currentIndex === 'number' ? (currentIndex === index ? '#FFAF00' : '#d4d4d4') : '#FFAF00'"
              :normalColor="typeof currentIndex === 'number' ? (currentIndex === index ? '#7C2D10' : '#d4d4d4') : '#7C2D10'"
              :sentence="handleSetMark(item.sentences_bh)" />
          </view>
        </template>
        <view class="scene-line"></view>
      </view>

      <recordSound @on-upload-success="onRecorderSuccess" />
    </view>
  </view>

  <CwCommon />
</template>

<script setup lang="ts">
import { ref, computed, onBeforeUnmount } from "vue";
import { rootFontSize } from "@/utils/util";
import customHeader from "@/components/customHeader.vue";
import loudspeaker from "@/components/loudspeaker.vue";
import sentence from "@/components/sentence.vue";
import recordSound, { type IUploadSuccessInfo } from "@/components/recordSound.vue";
import { onLoad, onHide } from "@dcloudio/uni-app";
import API from "@/api";
import env from "@/config/env";
import { startEvaluating } from "@/utils/chivox";
import { util } from "@/utils/util";
import type { ISceneSpeakLesson, ISceneSpeak } from "./index";
import { useDelayShow } from "@/hooks/useDelayShow";

const { delayShow } = useDelayShow();

const scoreLimit = ref(0);
const currentIndex = ref<number | string>("");
const curSceneSpeak = ref<ISceneSpeak>({
  img: "",
  uk_voice: "",
  us_voice: "",
  sentences: "",
  sentences_bh: "",
  scene_speak_id: 0,
  option: [],
});

const currentOption = computed(() => {
  if (typeof currentIndex.value === "number") {
    return curSceneSpeak.value.option[currentIndex.value];
  }
  return null;
});

const scene_speak = ref<any[]>([]);

const fs = uni.getFileSystemManager();
const height = ref(getApp().globalData!.pageProcessTop);

const sectionId = ref("");
const progress = ref(0);
const stepProcess = ref(0);
const optionTags = ["A", "B", "C", "D"];
const courseStep = ref("");
const studyTime = ref(0);
const isRelearn = ref(false); // 判断是否是重学
const isReStart = ref(false); // 再次重新开始
const isSynthesis = ref(true); // 是否是口语综合

let timer: number | undefined;

onLoad(async (option: any) => {
  sectionId.value = option.section_id;
  courseStep.value = option.courseStep;
  isReStart.value = option.isReStart === "true";
  if (option.isSynthesis) {
    isSynthesis.value = option.isSynthesis === "true";
  }

  if (option.data) {
    const result: ISceneSpeakLesson = JSON.parse(decodeURIComponent(option.data));

    isRelearn.value = result.isRelearn;
    scoreLimit.value = result.data.scoreLimit;
    stepProcess.value = 100 / result.data.stepLength;
    curSceneSpeak.value = result.data.questions;
    progress.value = Math.max(0, Math.min(100, stepProcess.value * result.data.currentQuestionIndex));
  }

  timer = setInterval(() => {
    studyTime.value += 1;
  }, 1000);
});

const handleSetMark = (sentence: string) => {
  return {
    mark: {
      begin: "<b>",
      end: "</b>",
    },
    content: sentence,
  }
}

const handleSetEvaluation = async (evaluation: any, ossFilePath: string) => {
  if (!(Array.isArray(evaluation.result.conf) && evaluation.result.conf.length)) {
    util.hideLoading();
    return util.showDialogue("发音不符合选项语句，请重试");
  }

  const maxScore = Math.max(...evaluation.result.conf);

  if (maxScore < scoreLimit.value) {
    util.hideLoading();
    return util.showDialogue("发音不符合选项语句，请重试");
  }

  const maxIndex = evaluation.result.conf.indexOf(maxScore);
  currentIndex.value = maxIndex;
  progress.value = Math.max(0, Math.min(100, progress.value + stepProcess.value));

  const singleVal = {
    user_voice: ossFilePath,
    analysis: JSON.stringify(evaluation),
    scene_speak_id: currentOption.value?.scene_speak_id,
  };

  scene_speak.value.push(singleVal); // 重学上报

  if (!isRelearn.value) {
    await API.sceneSpeakReport({
      section_id: sectionId.value,
      scene_speak: JSON.stringify([singleVal]),
    });

    util.hideLoading();
  }

  if (curSceneSpeak.value.option[maxIndex]?.list) {
    setTimeout(() => {
      // @ts-ignore
      curSceneSpeak.value = curSceneSpeak.value.option[maxIndex].list;
      currentIndex.value = "";
    }, 1000);
    util.hideLoading();
  } else {
    if (isRelearn.value) {
      await API.sceneSpeakReport({
        section_id: sectionId.value,
        scene_speak: JSON.stringify(scene_speak.value),
      });
      util.hideLoading();
    }

    let temp = {};
    if (isReStart.value) {
      temp = {
        isRelearn: true,
      }
    }

    uni.redirectTo({
      url: `/pages/lowPricedCourse/situationalDialog/scoreOverall/index?section_id=${sectionId.value}&headerTitle=情景对话&data=${encodeURIComponent(JSON.stringify(temp))}&type=${courseStep.value}&isReStart=${isReStart.value}&isSynthesis=${isSynthesis.value}`,
    });
  }
};

const handleSetOptions = () => {
  let options: string[] = [];
  // @ts-ignore
  const optionList = curSceneSpeak.value?.option || curSceneSpeak.value?.list;

  optionList?.forEach((item) => {
    options.push(item.sentences);
  });

  return options;
};

const onRecorderSuccess = (info: IUploadSuccessInfo) => {
  util.showLoading();
  fs.readFile({
    filePath: info.localFilePath,
    success: (res) => {
      startEvaluating({
        evaluatingInfo: { options: handleSetOptions() },
        audioBuffer: res.data as ArrayBuffer,
        onSuccess: (val) => {
          handleSetEvaluation(val, info.ossFilePath);
        },
        onError: (errMsg) => {
          util.hideLoading();
          util.showDialogue(errMsg);
        },
      });
    },
    fail: () => {
      util.hideLoading();
      util.showDialogue("找不到音频文件");
    },
  });
};

const handleTimeLongReport = async () => {
  await API.timeLongReport({
    section_id: sectionId.value,
    is_first: isRelearn.value ? 0 : 1,
    time_long: studyTime.value,
  });
};

onBeforeUnmount(async () => {
  clearInterval(timer);
  await handleTimeLongReport();

  studyTime.value = 0;
});
</script>

<style scoped lang="scss">
.page-container {
  width: 100vw;
  height: 100vh;
  background-color: #ffffff;

  .scene-container {
    position: absolute;
    width: 37.5rem;
    top: 6rem;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    overflow: hidden;

    .scene-wrapper {
      width: 100%;
      height: calc(100% - 0.5rem);
      overflow: auto;

      .scene-label {
        margin-left: 2rem;
        font-size: 1.6rem;
        font-weight: 400;
        font-family: xiaolai;
        color: $uni-text-color;
      }

      .scene-doubt {
        position: relative;
        display: flex;
        justify-content: center;
        width: 33.5rem;
        height: 16rem;
        margin: 2.2rem 2rem 2rem;

        .horn {
          position: absolute;
          bottom: 0.9rem;
          left: 0.9rem;
          width: 3.3rem;
          height: 3.3rem;
          z-index: 1;
          border-radius: 50%;
          background-color: #FDF2E0;
        }

        .person {
          width: 33.5rem;
          height: 16rem;
          border-radius: 1rem;
        }
      }

      .scene-answer {
        margin-left: 2rem;
        margin-bottom: 1rem;
        font-size: 1.5rem;
        font-weight: 400;
        font-family: xiaolai;
        color: $uni-text-color;
      }

      .scene-option {
        display: flex;
        align-items: center;
        margin: 1rem 2rem 0.8rem;
        padding: 2rem;
        font-size: 1.6rem;
        font-family: xiaolai;
        font-weight: 400;
        border-radius: 30rpx;

        .option-tag {
          width: 2rem;
        }

        .option-label {
          margin-left: 0.8rem;
        }
      }

      .active {
        color: $uni-text-color;
        border: 2px solid $uni-border-color;
        background-color: $uni-bg-color;
      }

      .un-active {
        color: #d4d4d4;
        border: 2px solid rgba(#fbeed7, 0.5);
        background-color: #ffffff;
      }

      .scene-line {
        height: 15rem;
      }
    }
  }
}
</style>
